home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / source / src / basic / _array.c next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  8.2 KB  |  447 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _array.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. #include <LEDA/impl/gen_array.h>
  16.  
  17. #define SWAP(a,b) { register GenPtr help = *a; *a = *b; *b = help; }
  18.  
  19. #define MIN_D 16 
  20.  
  21. void gen_array::read(istream& in, string s)
  22. { cout << s;
  23.   int i = 0; 
  24.   while (in && i<sz)
  25.   { clear_entry(v[i]);
  26.     read_el(v[i],in);
  27.     i++;
  28.    }
  29.  }
  30.  
  31. void gen_array::print(ostream& out, string s, char space) const
  32. { cout << s;
  33.   int i = 0; 
  34.   while (i < sz)
  35.     { out << string("%c",space);
  36.       print_el(v[i],out); 
  37.       i++;
  38.      }
  39.   out.flush();
  40. }
  41.  
  42. void gen_array::clear() 
  43. { register int i = sz;
  44.   register GenPtr* vv = &v[i];
  45.   while (i--) clear_entry(*--vv);
  46. }
  47.  
  48. void gen_array::init() 
  49. { register int i = sz;
  50.   register GenPtr* vv = &v[i];
  51.   while (i--) init_entry(*--vv);
  52. }
  53.  
  54. gen_array::gen_array()
  55. { Low = 0;
  56.   High = -1;
  57.   sz = 0;
  58.   v = 0;
  59. }
  60.  
  61.  
  62. gen_array::gen_array(int a, int b)
  63. { if (a>b) error_handler(1,"bad array size");
  64.   Low = a;
  65.   High = b;
  66.   sz = b-a+1;
  67.   v = new GenPtr[sz+1];
  68.   if (v==0) error_handler(99,"array: out of memory");
  69.   register int i = sz;
  70.   register GenPtr* vv = &v[i];
  71.   while (i--) init_entry(*--vv);
  72.  }
  73.  
  74. gen_array::gen_array(int n)
  75. { Low = 0;
  76.   High = n-1;
  77.   sz = n;
  78.   v = new GenPtr[sz+1];
  79.   if (v==0) error_handler(99,"array: out of memory");
  80.   register int i = sz;
  81.   register GenPtr* vv = &v[i];
  82.   while (i--) init_entry(*--vv);
  83. }
  84.  
  85. gen_array::gen_array(const gen_array& a)
  86. { register i = a.sz;
  87.   sz = i;       
  88.   Low = a.Low;
  89.   High = a.High;
  90.   v = new GenPtr[i+1];
  91.   register GenPtr* vv = &v[i];
  92.   register GenPtr* av = &a.v[i];
  93.   while (i--) 
  94.   { *--vv = *--av;
  95.     copy_entry(*vv);
  96.    }
  97. }
  98.  
  99. gen_array& gen_array::operator=(const gen_array& a)
  100. { if (this != &a)
  101.   { register i = a.sz;
  102.     if (sz != i)
  103.     { sz = i;       
  104.       clear();
  105.       delete v;
  106.       v = new GenPtr[i+1];
  107.     }
  108.     Low = a.Low;
  109.     High = a.High;
  110.     register GenPtr* vv = &v[i];
  111.     register GenPtr* av = &a.v[i];
  112.     while (i--) 
  113.     { *--vv = *--av;
  114.       copy_entry(*vv);
  115.      }
  116.   }
  117.  return *this;
  118. }
  119.  
  120. void gen_array::permute(int l, int r)
  121. {
  122.   if (l<Low || l>High || r<l || r>High) 
  123.          error_handler(2,"array::permute illegal range");
  124.  
  125.   l -= Low;
  126.   r -= Low;
  127.  
  128.   register GenPtr* x;
  129.   register GenPtr* y;
  130.   register GenPtr* stop = v+r+1;
  131.  
  132.   init_random();
  133.   for(x=v+l;x!=stop;x++) 
  134.   { y = v+random(l,r);  
  135.     SWAP(x,y);  
  136.    }
  137. }
  138.  
  139. static int min_d;
  140.  
  141. void gen_array::quick_test(GenPtr* l, GenPtr* r)
  142.   register GenPtr  s;
  143.   register GenPtr* k;
  144.   register GenPtr* i = l+random()%(r-l);
  145.  
  146.   SWAP(i,l);
  147.   i = l;
  148.   k = r+1;
  149.   s = *l;
  150.  
  151.   for(;;)
  152.   { while (*(++i) < s);
  153.     while (*(--k) > s);
  154.     if (i<k) SWAP(i,k) else break;
  155.    }
  156.  
  157.   SWAP(l,k);
  158.  
  159.   if (l < k-min_d) quick_test(l,k-1);
  160.   if (r > k+min_d) quick_test(k+1,r);
  161. }
  162.  
  163. void gen_array::sort_test(int d) 
  164. {
  165.   GenPtr* left  = v;
  166.   GenPtr* right = v+sz-1;
  167.   GenPtr* min_stop = left + d;
  168.  
  169.   if (min_stop > right) min_stop = right;
  170.  
  171.   v[sz] = GenPtr(MAXINT);
  172.  
  173.   min_d = d;
  174.   quick_test(left,right);
  175.   if (d>1) int_insertion_sort(left,right,min_stop);
  176.  }
  177.  
  178.  
  179. void gen_array::sort(int l, int h, CMP_PTR f) 
  180. {
  181.   GenPtr* left  = v+l-Low;
  182.   GenPtr* right = v+h-Low;
  183.   GenPtr* min_stop = left + MIN_D;
  184.  
  185.   if (min_stop > right) min_stop = right;
  186.  
  187.   if (f)
  188.      { quick_sort(left,right,f);
  189.        insertion_sort(left,right,min_stop,f);
  190.       }
  191.   else
  192.      if (int_type())
  193.       { int_quick_sort(left,right);
  194.         int_insertion_sort(left,right,min_stop);
  195.        }
  196.      else
  197.        { quick_sort(left,right);
  198.          insertion_sort(left,right,min_stop);
  199.         }
  200.  }
  201.  
  202.  
  203. void gen_array::quick_sort(GenPtr* l, GenPtr* r)
  204.   register GenPtr* i = l+(r-l)/2; //l+random()%(r-l);
  205.   register GenPtr* k;
  206.  
  207.   if (cmp(*i,*r) > 0) SWAP(i,r);
  208.   SWAP(l,i);
  209.  
  210.   GenPtr  s = *l;
  211.  
  212.   i = l;
  213.   k = r;
  214.  
  215.   for(;;)
  216.   { while (cmp(*(++i),s)<0);
  217.     while (cmp(*(--k),s)>0);
  218.     if (i<k) SWAP(i,k) else break;
  219.    }
  220.  
  221.   SWAP(l,k);
  222.  
  223.   if (k > l+MIN_D) quick_sort(l,k-1);
  224.   if (r > k+MIN_D) quick_sort(k+1,r);
  225. }
  226.  
  227.  
  228. void gen_array::quick_sort(GenPtr* l, GenPtr* r, CMP_PTR usr_cmp)
  229.   register GenPtr* i = l+(r-l)/2; //l+random()%(r-l);
  230.   register GenPtr* k;
  231.  
  232.   if (usr_cmp(*i,*r) > 0) SWAP(i,r);
  233.   SWAP(l,i);
  234.  
  235.   GenPtr  s = *l;
  236.  
  237.   i = l;
  238.   k = r;
  239.  
  240.   for(;;)
  241.   { while (usr_cmp(*(++i),s)<0);
  242.     while (usr_cmp(*(--k),s)>0);
  243.     if (i<k) SWAP(i,k) else break;
  244.    }
  245.  
  246.   SWAP(l,k);
  247.  
  248.   if (k > l+MIN_D) quick_sort(l,k-1,usr_cmp);
  249.   if (r > k+MIN_D) quick_sort(k+1,r,usr_cmp);
  250. }
  251.  
  252.  
  253. void gen_array::int_quick_sort(GenPtr* l, GenPtr* r)
  254.   register GenPtr* i = l+(r-l)/2; //l+random()%(r-l);
  255.   register GenPtr* k;
  256.  
  257.   if (*i > *r) SWAP(i,r);
  258.   SWAP(l,i);
  259.  
  260.   GenPtr  s = *l;
  261.  
  262.   i = l;
  263.   k = r;
  264.  
  265.   for(;;)
  266.   { while (*(++i) < s);
  267.     while (*(--k) > s);
  268.     if (i<k) SWAP(i,k) else break;
  269.    }
  270.  
  271.   SWAP(l,k);
  272.  
  273.   if (k > l+MIN_D) int_quick_sort(l,k-1);
  274.   if (r > k+MIN_D) int_quick_sort(k+1,r);
  275. }
  276.  
  277. void gen_array::insertion_sort(GenPtr* l, GenPtr* r, GenPtr* min_stop, 
  278.                                CMP_PTR usr_cmp)
  279. {
  280.   register GenPtr* min=l;
  281.   register GenPtr* run;
  282.   register GenPtr* p;
  283.   register GenPtr* q;
  284.  
  285.   for (run = l+1; run <= min_stop; run++)
  286.       if (usr_cmp(*run,*min) < 0) min = run;
  287.  
  288.   SWAP(min,l);
  289.  
  290.   if (r == l+1) return;
  291.  
  292.   for(run=l+2; run <= r; run++)
  293.   { for (min = run-1; usr_cmp(*run,*min) < 0; min--);
  294.     min++;
  295.     if (run != min) 
  296.     { GenPtr save = *run;
  297.       for(p=run, q = run-1; p > min; p--,q--) *p = *q;
  298.       *min = save;
  299.      }
  300.    }
  301. }
  302.  
  303.  
  304. void gen_array::insertion_sort(GenPtr* l, GenPtr* r, GenPtr* min_stop)
  305. {
  306.   register GenPtr* min=l;
  307.   register GenPtr* run;
  308.   register GenPtr* p;
  309.   register GenPtr* q;
  310.  
  311.   for (run = l+1; run <= min_stop; run++)
  312.       if (cmp(*run,*min) < 0) min = run;
  313.  
  314.   SWAP(min,l);
  315.  
  316.   if (r == l+1) return;
  317.  
  318.   for(run=l+2; run <= r; run++)
  319.   { for (min = run-1; cmp(*run,*min) < 0; min--);
  320.     min++;
  321.     if (run != min) 
  322.     { GenPtr save = *run;
  323.       for(p=run, q = run-1; p > min; p--,q--) *p = *q;
  324.       *min = save;
  325.      }
  326.    }
  327. }
  328.  
  329.  
  330.  
  331. void gen_array::int_insertion_sort(GenPtr* l, GenPtr* r, GenPtr* min_stop)
  332. {
  333.   register GenPtr* min=l;
  334.   register GenPtr* run;
  335.   register GenPtr* p;
  336.   register GenPtr* q;
  337.  
  338.   for (run = l+1; run <= min_stop; run++)
  339.       if (*run <  *min) min = run;
  340.  
  341.   SWAP(min,l);
  342.  
  343.   if (r == l+1) return;
  344.  
  345.   for(run=l+2; run <= r; run++)
  346.   { for (min = run-1; *run < *min; min--);
  347.     min++;
  348.     if (run != min) 
  349.     { GenPtr save = *run;
  350.       for(p=run, q = run-1; p > min; p--,q--) *p = *q;
  351.       *min = save;
  352.      }
  353.    }
  354. }
  355.  
  356.  
  357.  
  358.  
  359. int gen_array::binary_search(GenPtr x)
  360. { int l = 0;
  361.   int r = sz-1;
  362.   int m;
  363.   while (l<r)
  364.   { m = (l+r)/2;
  365.     if (cmp(x,elem(m))==0) { l = m; break; }
  366.     if (cmp(x,elem(m)) > 0) l = m+1;
  367.     else
  368.     if (cmp(x,elem(m)) < 0) r = m-1;
  369.    }
  370.  
  371.   return  (cmp(elem(l),x)==0) ? (l+Low) : (Low-1);
  372. }
  373.  
  374. int gen_array::binary_search(GenPtr x, CMP_PTR usr_cmp)
  375. { int l = 0;
  376.   int r = sz-1;
  377.   int m;
  378.   while (l<r)
  379.   { m = (l+r)/2;
  380.     if (usr_cmp(x,elem(m))==0) { l = m; break; }
  381.     if (usr_cmp(x,elem(m)) > 0) l = m+1;
  382.     else
  383.     if (usr_cmp(x,elem(m)) < 0) r = m-1;
  384.    }
  385.  
  386.   return  (usr_cmp(elem(l),x)==0) ? (l+Low) : (Low-1);
  387. }
  388.  
  389. int gen_array::int_binary_search(GenPtr x)
  390. { int l = 0;
  391.   int r = sz-1;
  392.   int m;
  393.   while (l<r)
  394.   { m = (l+r)/2;
  395.     if (x ==elem(m)) { l = m; break; }
  396.     if (x > elem(m)) 
  397.        l = m+1;
  398.     else
  399.        if (x < elem(m)) r = m-1;
  400.    }
  401.  
  402.   return  (elem(l) == x) ? (l+Low) : (Low-1);
  403. }
  404.  
  405.  
  406.  
  407. void gen_array2::init(int a, int b, int c, int d)
  408. { register int i,j;
  409.   for (i=a;i<=b;i++) 
  410.       for (j=c; j<=d; j++) init_entry(row(i)->entry(j));
  411. }
  412.  
  413. gen_array2::gen_array2(int a, int b, int c, int d) : A(a,b) 
  414. { Low1  = a;
  415.   High1 = b;
  416.   Low2  = c;
  417.   High2 = d;
  418.   while (b>=a) A.entry(b--) = (GenPtr) new gen_array(c,d); 
  419. }
  420.  
  421. gen_array2::gen_array2(int a, int b) : A(a) 
  422. { Low1  = 0;
  423.   High1 = a-1;
  424.   Low2  = 0;
  425.   High2 = b-1;
  426.   while (a>0) A.entry(--a) = (GenPtr) new gen_array(b); 
  427. }
  428.  
  429. void gen_array2::clear()
  430. { register int i,j;
  431.   for (i=Low1;i<=High1;i++) 
  432.   for (j=Low2;j<=High2;j++) 
  433.   clear_entry(row(i)->entry(j));
  434. }
  435.  
  436. gen_array2::~gen_array2()
  437. { register int i;
  438.   for (i=Low1;i<=High1;i++) delete (gen_array*)A.entry(i);
  439. }
  440.  
  441.  
  442.